package com.googlecode.dgwt.client.dijit.theme;

import com.google.gwt.core.client.GWT;
import com.googlecode.dgwt.client.dijit.Dijit;
import com.googlecode.dgwt.client.dijit.Widget;
import com.googlecode.dgwt.client.dijit.base.PanelWidget;
import com.googlecode.dgwt.client.dijit.resource.stylesheet.StyleSheetResources;
import com.googlecode.dgwt.client.dijit.theme.impl.StyleSheetTheme;

/**
 * Basic theme for Dijit Widgets.
 * 
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class Theme extends StyleSheetTheme {


    /**
     * Style Sheet declarations used in this Theme.
     */
    private final StyleSheetResources STYLE_SHEETS = GWT.create(StyleSheetResources.class);


    /**
     * Instance of default Dijit Theme.
     */
    private static Theme defaultTheme;
    

    /**
     * Gets an instance of the default Theme.
     * @return Theme
     */
    public static Theme getDefaultTheme(){
        if (defaultTheme == null){
            defaultTheme = GWT.create(Theme.class);
        }
        return defaultTheme;
    }

    
    /**
     * Event that occurs when this Theme is set using {@link Dijit#setTheme(Theme)}
     * @see com.googlecode.dgwt.client.dijit.Dijit#setTheme(Theme)
     */
    @Override
    public void onLoad() {
        super.onLoad();
        document().importDeclaration();        
    }
    

    
    /*-- Default Style for Widgets --*/

    
    
    /**
     * Gets the default style for a {@link Widget} descendant. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getWidgetStyle() { 
        return ""; 
    }
    
    /**
     * Gets the default style for a {@link PanelWidget} descendant. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getPanelStyle() { 
        return "background: #fff;";
    }
    
    /**
     * Gets the default style for a {@link PanelWidget} descendant that has a border. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getBorderPanelStyle() { 
        return "border: 1px solid #B3B3B3;";
    }
    
    /**
     * Gets the default style for list or table row. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getRowStyle(){
        return "";
    }
    
    /**
     * Gets the default style for list or table cell. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getCellStyle(){        
        return "border: 1px solid #FFF;";
    }
    
    /**
     * Gets the default style for collation of list or table row. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getRowOddStyle(){
        return "background-color: #F2F5F9;";
    }
    
    /**
     * Gets the default style for collation of list or table cell. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getCellOddStyle(){        
        return "";
    }
    
    /**
     * Gets the default style for list or table row when mouse is hover it. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getRowHoverStyle(){
        // FIXME achar uma boa cor
        return "background-color: #f00;";
    }
    
    /**
     * Gets the default style for list or table cell when mouse is hover it. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getCellHoverStyle(){
        return "";
    }
    
    /**
     * Gets the default style for list or table row when it is selected. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getRowSelectedStyle() {
        return "background-color: #AEC7E3;";
    }

    /**
     * Gets the default style for list or table cell when it is selected. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getCellSelectedStyle() {
        return "border-color: #AEC7E3;";
    }

    /**
     * Gets the default style for list or table row when it is focused. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getRowFocusedStyle() {
        return "";
    }

    /**
     * Gets the default style for list or table cell when it is focused. <br/>
     * Example: </br> </br> 
     * <code>
     *    border: 1px solid black; </br>
     * </code> 
     * </br> Note that we must always end with a semicolon ";".
     * 
     * @return any valid CSS style
     */
    public String getCellFocusedStyle() {
        return "border-top: 1px dotted #555;" +
               "border-bottom: 1px dotted #555;";
    }


    
    /*-- Dependent Style Classes --*/
    
    

    public String getDependentSeparator() {
        return ""; // TODO definir como "-" e fazer todos os dependents ter letras iniciais minusculas;
    }
    
    public String getReadOnlyName() {
        return "Readonly";
    }
    
    public String getDisabledName() {
        return "Disabled";
    }
    
    public String getHoverName() {
        return "Hover";
    }

    public String getActiveName() {
        return "Active";
    }
    
    public String getFocusedName() {
        return "Focused";
    }

    public String getSelectedName() {
        return "Selected";
    }

    public String getChildrenName() {
        return "Child";
    }
    
    public String getRowName(){
        return "Row";
    }

    public String getCellName(){
        return "Cell";
    }

    public String getOddName(){
        return "Odd";
    }
    
    public String getSelectorName(){
        return "Selector";
    }
    
    public String getHiddenFocus(){
        return "HiddenFocus";
    }
    
    
    
    /*-- Dijit State Style Classes --*/

    
    
    public final String dijitReadOnlyName() {
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getReadOnlyName();
    }
    
    public final String dijitDisabledName() {
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getDisabledName();
    }
    
    public final String dijitHoverName() {
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getHoverName();
    }

    public final String dijitActiveName() {
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getActiveName();
    }
    
    public final String dijitFocusedName() {
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getFocusedName();
    }
    
    public final String dijitSelectedName() {
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getSelectedName();
    }

    public final String dijitChildrenName() {
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getChildrenName();
    }

    public final String dijitRowName(){
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getRowName();
    }
    
    public final String dijitCellName(){
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getCellName();
    }
    
    public final String dijitOddName(){
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getOddName();
    }
    
    public final String dijitSelectorName(){
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getSelectorName();
    }
    
    public final String dijitHiddenFocusName(){
        return Dijit.BASE_CLASSNAME + getDependentSeparator() + getHiddenFocus();
    }
    
    
    
    /*-- HTML Document --*/

    
    
    protected static final String DOCUMENT_BASE_CLASS = " ";

    
    /**
     * Standard CSS for the HTML document
     */
    protected CSS document(){
        return getStyleSheetEngine().create(DOCUMENT_BASE_CLASS);
    }

    
    
    /*-- dijit --*/

    
    
    /**
     * Global CSS for Dijit Themes
     */
    protected CSS dijit() {
        CSS css = getStyleSheetEngine().create(Dijit.BASE_CLASSNAME);
        if (css.isEmpty()){
            css.setDeclaration(STYLE_SHEETS.dijit());
        }
        return css;
    }


    protected CSS dijitReset() {
        CSS css = getStyleSheetEngine().create("dijitReset");
        if (css.isEmpty()){
            css.addSuperClass(dijit());
            css.setDeclaration(STYLE_SHEETS.dijitReset());
        }
        return css;
    }


    protected CSS dijitLeft() {
        CSS css = getStyleSheetEngine().create("dijitLeft");
        if (css.isEmpty()){
            css.addSuperClass(dijit());
            css.setDeclaration(STYLE_SHEETS.dijitLeft());
        }
        return css;
    }


    public CSS dijitWidget() {
        CSS css = getStyleSheetEngine().create("dijitWidget");
        if (css.isEmpty()){
            css.addSuperClass(dijit());
            //css.setDeclaration(STYLE_SHEETS.dijitWidget());
        }
        return css;
    }

    
    public CSS dijitFocusWidget() {
        CSS css = getStyleSheetEngine().create("dijitFocusWidget");
        if (css.isEmpty()){
            css.addSuperClass(dijitWidget());
            //css.setDeclaration(STYLE_SHEETS.dijitFocusWidget());
        }
        return css;
    }

    
    public CSS dijitPanelWidget() {
        CSS css = getStyleSheetEngine().create("dijitPanelWidget");
        if (css.isEmpty()){
            css.addSuperClass(dijitWidget());
            //css.setDeclaration(STYLE_SHEETS.dijitPanelWidget());
        }
        return css;
    }

    
    public CSS dijitBorderPanel() {
        CSS css = getStyleSheetEngine().create("dijitBorderPanel");
        if (css.isEmpty()){
            css.addSuperClass(dijitPanelWidget());
            css.setDeclaration(STYLE_SHEETS.dijitBorderPanel());
        }
        return css;
    }


    /**
     * @see com.googlecode.dgwt.client.dijit.Toolbar
     */
    public CSS dijitToolbar() {
        CSS css = getStyleSheetEngine().create("dijitToolbar");
        if (css.isEmpty()){
            css.addSuperClass(dijit());
            css.setDeclaration(STYLE_SHEETS.dijitToolbar());
        }
        return css;
    }



    /*-- dijit.view --*/
    
    

    public CSS dijitIndexedView() {
        CSS css = getStyleSheetEngine().create("dijitIndexedView");
        if (css.isEmpty()){
            css.addSuperClass(dijitWidget());
            css.setDeclaration(STYLE_SHEETS.dijitIndexedView());
        }
        return css;
    }

    

    /*-- dijit.form --*/

    
    
    /**
     * @see com.googlecode.dgwt.client.dijit.form.Label
     */
    public CSS dijitLabel(){ 
        CSS css = getStyleSheetEngine().create("dijitLabel");
        if (css.isEmpty()){
            css.addSuperClass(dijitWidget());
            //css.setDeclaration(STYLE_SHEETS.dijitLabel());
        }
        return css;
    }

    
    /**
     * @see com.googlecode.dgwt.client.dijit.form.Button
     */
    public CSS dijitButton(){ 
        CSS css = getStyleSheetEngine().create("dijitButton");
        if (css.isEmpty()){
            css.addSuperClass(dijitFocusWidget());
            css.setDeclaration(STYLE_SHEETS.dijitButton());
        }
        return css;
    }

    
    /**
     * @see com.googlecode.dgwt.client.dijit.form.TextBox
     */
    public CSS dijitTextBox() {
        CSS css = getStyleSheetEngine().create("dijitTextBox");
        if (css.isEmpty()){
            css.addSuperClass(dijitReset(), dijitLeft(), dijitFocusWidget());
            css.setDeclaration(STYLE_SHEETS.dijitTextBox());
        }
        return css;
    }
    
    

    /*-- dijit.layout --*/
    
    

    /**
     * @see com.googlecode.dgwt.client.dijit.layout.HFlexPanel
     */
    public CSS dijitHFlexPanel(){
        CSS css = getStyleSheetEngine().create("dijitHFlexPanel");
        if (css.isEmpty()){
            css.addSuperClass(dijitPanelWidget());
            css.setDeclaration(STYLE_SHEETS.dijitHFlexPanel());
        }
        return css;
    };


    /**
     * @see com.googlecode.dgwt.client.dijit.layout.VFlexPanel
     */
    public CSS dijitVFlexPanel(){
        CSS css = getStyleSheetEngine().create("dijitVFlexPanel");
        if (css.isEmpty()){
            css.addSuperClass(dijitPanelWidget());
            css.setDeclaration(STYLE_SHEETS.dijitVFlexPanel());
        }
        return css;
    }


    /**
     * @see com.googlecode.dgwt.client.dijit.layout.ScrollPanel
     */
    public CSS dijitScrollPanel(){
        CSS css = getStyleSheetEngine().create("dijitScrollPanel");
        if (css.isEmpty()){
            css.addSuperClass(dijitPanelWidget());
            css.setDeclaration(STYLE_SHEETS.dijitScrollPanel());
        }
        return css;
    }


    /**
     * @see com.googlecode.dgwt.client.dijit.form.ListBox
     */
    public CSS dijitListBox(){
        CSS css = getStyleSheetEngine().create("dijitListBox");
        if (css.isEmpty()){
            css.addSuperClass(dijitBorderPanel()); // FIXME criar herança de dijitTextBox
            css.setDeclaration(STYLE_SHEETS.dijitListBox());
        }
        return css;
    }

}
